chrispanag
(Christos Panagiotakopoulos)
12월 17, 2020, 7:37오전
21
먼저 도움 주셔서 정말 감사합니다! 어쨌든 흥미로운 버그네요.
문제는 라우트가 사용 가능하지 않아서 데이터베이스를 통해 사용자 이름을 변경해야 할 수도 있다는 겁니다.
쿼리를 제공해 주실 수 있을까요?
그것은 불가능하다고 생각합니다. 그렇게 하면 그리스에서 Σ로 시작하는 많은 이름들이 금지되어 해당 사용자의 Facebook 로그인이 사실상 깨질 테니까요. 특정 정규식 패턴을 금지할 수 있을까요? 그러면 Σ가 적어도 끝부분에 위치하도록 보장할 수 있을 것 같습니다.
1개의 좋아요
chrispanag
(Christos Panagiotakopoulos)
12월 17, 2020, 12:45오후
22
다른 회원 한 명이 정확히 동일한 문제로 가입했습니다. 제가 여기서 강조하려는 점은, 우리에게는 이것이 경계 사례(edge-case)가 아니라는 것입니다. 그리스어 이름 중 이름 끝에 Σ(또는 ς)를 사용하는 이름이 실제로 수천 개나 됩니다.
그리고 불행히도, 우리의 주요 연령층(40세 이상)을 고려하면, 페이스북에 이름을 전부 대문자로 적어둔 회원들이 매우 많습니다 ( ) . 따라서 페이스북 로그인을 사용하면 이름이 사용자 이름 필드에 그대로 복사됩니다…
4개의 좋아요
gerhard
(Gerhard Schlager)
12월 17, 2020, 3:34오후
23
Postgres에 대해서는 걱정하지 않으셔도 됩니다. SQL에서는 항상 username_lower를 비교해야 하며 LOWER()에 의존해서는 안 됩니다. username_lower는 단순히 사용자명의 소문자 버전이 아니기 때문입니다. 우리는 유니코드 정규화도 적용하고 있습니다.
동의합니다. 지금은 User.normalize_username에 우회 처리를 추가하는 것으로 충분할 것입니다. Ruby 버그 관련 토론에서 이미 논의가 이루어지고 있으며, 쉬운 해결책이 없어 보입니다. 하지만 우리는 운이 좋습니다. 사용자명의 마지막 문자만 확인하면 되기 때문입니다. 이는 완전한 문장에서 처리하는 것보다 훨씬 쉽습니다.
4개의 좋아요
chrispanag
(Christos Panagiotakopoulos)
12월 17, 2020, 3:51오후
24
gerhard:
사용자 이름의 마지막 문자를 확인
음… 이 사용자 이름은 어떻게 처리될까요?
대문자: ΧΡΗΣΤΟΣ_ΠΑΝΑΓΙΩΤΑΚΟΠΟΥΛΟΣ
소문자: χρηστος_παναγιωτακοπουλος 또는 χρηστοσ_παναγιω타κοπουλος
NodeJs는 이를 올바르게 처리하지만, 사용자 이름의 마지막 문자만 확인한다면 문제가 지속될 것입니다.
(그리스어 남성 이름의 거의 모든 것, 이름과 성 모두, Σ로 끝납니다)
3개의 좋아요
gerhard
(Gerhard Schlager)
12월 17, 2020, 3:57오후
25
맞아. 그래도 전체 구현보다는 훨씬 쉬울 거야. 밑줄이나 대시, 그리고 숫자 같은 특정 기호만 신경 쓰면 되니까. 충분히 해볼 만할 것 같아.
2개의 좋아요
chrispanag
(Christos Panagiotakopoulos)
12월 17, 2020, 4:27오후
26
이 특정 버그 논의에서 벗어나고 있다는 건 알지만, 이 문제를 생각할 때마다 이를 피할 수 있다는 사실을 무시할 수 없습니다.
discourse에서 사용자를 userId로 참조하는 API 경로와 username으로 참조하는 경로가 혼재되어 있다는 것을 발견했습니다. userId를 중심으로 더 일관되게 만들어서는 안 될까요?
예를 들어, 현재 카테고리/태그에서처럼 URL에 username과 userId를 모두 포함하는 방식(https://meta.discourse.org/u/chrispanag/4387)을 도입하는 건 어떨까요?
그냥 아이디어입니다
2개의 좋아요
riking
(Kane York)
12월 18, 2020, 8:13오후
28
이 작업을 위해서는 정리 작업이 필요할 것입니다. LOWER() 호출이 몇 군데 있는 것을 분명히 확인했습니다.
4개의 좋아요
sam
(Sam Saffron)
12월 20, 2020, 10:00오후
29
지난 몇 년간 이 문제가 계속 제기되어 왔습니다: Update quotes and mentions when username is changed - #10 by sam
2016년에 @eviltrout은 이에 반대했는데, 요즘 그의 입장이 어떻게 변했는지 확실하지 않습니다.
어쨌든, 저는 Discourse에서 이 PR으로 우회 해결책을 마련했습니다:
master ← final_sigma
merged 09:51PM - 22 Dec 20 UTC
Final sigma is not lower cased correctly in Ruby causing issues with routing.
T… his works around the issue by downcasing all usernames containing a sigma using JS.
이 PR은 시그마(σ)로 시작하는 사용자 이름을 소문자로 변환하여 Facebook의 신규 가입 문제를 처리합니다. 즉, Spiros의 사용자 이름과 최종 시그마(ς)를 사용하는 다른 사용자들의 이름만 소문자로 수정하면 이 문제가 장기적으로 해결될 것입니다.
(PR 병합 대기 중)
4개의 좋아요
chrispanag
(Christos Panagiotakopoulos)
12월 20, 2020, 11:17오후
30
감사합니다 @sam ! 정말 큰 도움이 되었습니다.
Rails 콘솔에서 이를 수행할 수 있는 방법이 있나요? (사용자가 손상되어 있어 관리자 패널을 통해 처리할 수 있는 방법이 없거든요…)
1개의 좋아요
sam
(Sam Saffron)
12월 20, 2020, 11:35오후
31
네, 이렇게 하면 됩니다
./launcher enter app
rails c
u = User.find_by(username: 'ΣΠΥΡΟΣ')
u.username = 'σπυρος'
u.username_lower = 'σπυρος'
u.save!`
4개의 좋아요
eviltrout
(Robin Ward)
12월 21, 2020, 4:55오후
32
여전히 모든 곳에 id를 사용하는 것을 좋아하지는 않지만, 그럴 만한 이유가 많은 경우들이 있다는 점은 이해합니다.
그런 경우에는 URL에 넣을 수 있는 어떤 값이든 username이라고 가정하고, id-username 같은 형태를 선호하겠습니다. 라우터가 이를 무시해도 괜찮습니다. 하지만 링크를 공유할 때, 어떤 것을 링크하고 있는지 최소한 감은 잡을 수 있을 테니까요.
6개의 좋아요
Falco
(Falco)
12월 21, 2020, 5:51오후
33
PostgreSQL의 경우, 적절한 정렬 규칙(collation)을 설정하면 문제가 해결되는 것으로 보입니다:
➜ discoursesmall git:(master) psql -d discourse_development
psql (13.1 (Ubuntu 13.1-1.pgdg20.10+1))
Type "help" for help.
discourse_development=# SELECT lower('ΣΠΥΡΟΣ');
lower
--------
σπυροσ
(1 row)
discourse_development=# SELECT lower('ΣΠΥΡΟΣ' COLLATE "und-x-icu");
lower
--------
σπυρος
(1 row)
출처: PostgreSQL: Re: BUG #15805: Problem with lower function for greek sigma (Σ) letter
7개의 좋아요
chrispanag
(Christos Panagiotakopoulos)
12월 21, 2020, 9:55오후
34
사실 ‘ß’ → ‘SS’ (독일어)와 같이 유사한 변환을 수행하는 다른 유니코드 문자들도 있습니다.
Discourse가 이러한 문자들을 어떻게 처리하는지 살펴보는 것도 흥미로울 것입니다.
또한 이 리소스도 확인해 보실 수 있습니다:
sam
(Sam Saffron)
12월 21, 2020, 10:28오후
35
개인적으로 사용자를 위한 Stack Overflow 스타일의 라우팅을 매우 좋아합니다:
https://stackoverflow.com/users/17174/sam-saffron
Discourse에서는 다음과 같은 형태가 될 것입니다:
https://meta.discourse.org/u/17174/sam-saffron
이 방식은 케이크도 먹고 남도 먹는, 일석이조의 효과를 줄 수 있습니다. 물론 "URL 어딘가에 17174 같은 ID가 있는 것을 싫어합니다. 사용자 이름은 안정적이니까요"라는 반론도 충분히 이해합니다.
그럼에도 불구하고, 우리는 지금까지 기존 라우팅 방식으로 잘 유지해 왔으며, 몇 년에 한 번 정도 엣지 케이스가 발생하는 수준입니다.
5개의 좋아요
위에서 설명한 대로, 적어도 사용자 프로필 페이지에서는 사용자 이름 대신 id를 사용하거나(또는 둘 다 사용하되 id에만 의존하는 방식) 사용하는 것이 도움이 될 것 같습니다. 이렇게 하면 사용자 이름에 문제가 발생했을 때, 관리자(Admin)가 rails 콘솔에서 명령어를 실행할 필요 없이 Discourse UI를 통해 사용자 이름을 변경할 수 있습니다.
gerhard
(Gerhard Schlager)
12월 22, 2020, 1:43오후
37
우리가 신경 써야 할 것은 소문자 변환 시 JavaScript와 Ruby 구현 방식이 다른 문자들뿐입니다. 반대 방향은 아닙니다.
독일어 소문자 "ß"를 대문자로 변환하는 규칙은 없습니다. “SS”, “SZ” 또는 새로운 대문자 “ẞ”(네, 미묘한 차이가 있습니다)가 될 수 있습니다. 이 과정을 역으로 수행하는 것은 "ẞ"에 대해서만 가능하며, 이는 Ruby와 JavaScript에서 모두 올바르게 작동합니다.
저는 다음을 수행해야 한다고 생각합니다:
즉각적인 문제를 해결하기 위해 @sam의 우회 방법을 병합합니다.
LOWER(username)를 SQL 쿼리에서 제거합니다. 이는 단순히 잘못된™ 관행이기 때문입니다(예: 유니코드 정규화 누락).
Ruby가 근본적인 문제를 수정하기를 바랍니다.
장기적으로: 루트에 사용자 ID를 추가하는 방안을 고려해 보겠습니다. 가장 어려운 부분은 인용과 멘션을 어떻게 처리할지 파악하는 것일 것입니다.
3개의 좋아요
znedw
(Zach Nedwich)
2월 23, 2021, 9:33오전
38
관련이 있을지 확실하지 않지만, 유니코드 이름을 가진 몇몇 사용자의 기록이 /log에 흩어져 있습니다.
ActionView::Template::Error (No route matches {:action=>"show", :controller=>"users", :username=>"ζηεδψ"}, possible unmatched constraints: [:username])